/*
 * ThreadTrap.java
 * - compute the interval
 * - compute the trapazoid for that interval
 */
public class ThreadTrap implements Runnable {
	private int numIntegral;
	private final double tolerance = 0.000005;
	private double a,b,I;
	private Thread t;
	
	public ThreadTrap(int numIntegral, double a, double b) {
		t = new Thread(this);
		this.a = a;
		this.b = b;
		this.I = 0.0;
		this.numIntegral = numIntegral;
		t.start();
	}// end constructor
	
	public void run() {
		try {	
			I = getFinalIntegral(a, b, numIntegral);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}// end method run
	
	private double doTrapazoid(double a, double b, int n){
	    double h = (b-a) / n;
	    double sum = 0.0;
	    for(int i = 1; i < n; i++) 
	    	sum += function(a + i * h);
	    return (b-a)*( function(a) + 2*sum + function(b)) / (2*n);  
	}// end method trapazoid
		
	private double getFinalIntegral(double a, double b, int n) {
		double I, I2, dev;
		// compute the initial estimates
		I = doTrapazoid(a, b, n);
		n = n*2;
		I2= doTrapazoid(a, b, n);
		if(I > I2)
			dev = (I-I2) / I2;
		else
			dev = (I2-I) / I ;  

		// unless the deviation is less than 0.000005, the routine keep computing.
		while(dev > tolerance) {
			I   = I2;
			n   = n*2;
			I2  = doTrapazoid(a , b, n);
			if(I > I2)
				dev = (I-I2) / I2;
			else
				dev = (I2-I) / I ;                     
		}
		return I;
	}// end method getFinalIntegral
	
	private double function(double x) {
	   return x*x+50*(Math.sin(100*Math.PI*x) * Math.sin(Math.PI*x));
	}// end method Function
	
	public Thread getThread() {
		return t;
	}// end method getThread
	
	public double getIntegral() {
		return I;
	}// end method getIntegral
}// end class ThreadTrap
